条件编译
有一种宏的使用几乎不可能避免。指令#ifdef identifier将条件性地导致随后的输入被忽略,直到遇到一个#endif指令。例如,
int f(int a
#ifdef arg_two
, int b
#endif
);
产生
int f(int a
);
给编译器去看,除非名为arg_two的宏义已经用#define定义。这种例子会把工具弄糊涂,而程序员通常总认为它们的行为是合理的。
#ifdef的大部分使用没有这么古怪。有节制地使用#ifdef不会有什么害处。另见9.3.3节。
用于控制#ifdef的名字应该仔细选择,使之不会与正常的标识符相冲突。例如,
struct Call_info {
Node* arg_one;
Node* arg_two;
// ...
};
这样看起来很清白的代码也可能产生混乱,假如某人写了:
#define arg_two x
不幸的是,普通的、无法避免的头文件里包含着许多危险且毫无必要的宏。
🔚